package com.example.e_comm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.e_comm.entity.User;
import com.example.e_comm.mapper.UserMapper;
import com.example.e_comm.service.UserService;
import com.example.e_comm.util.RedisUtil;
import com.example.e_comm.util.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class UserServiceImpl
        extends ServiceImpl<UserMapper, User>
implements UserService {
@Autowired
private RedisUtil redisUtil;
@Autowired
private TokenUtil tokenUtil;

    @Override
    public boolean register(User user) {
        //查重：username,email
        if(this.count(new QueryWrapper<User>()
                .eq("username", user.getUsername()))>0){
            throw new IllegalArgumentException("用户名已存在,请替换其他用户名！");
        }
        if (this.count(new QueryWrapper<User>()
                .eq("email", user.getEmail()))>0){
            throw new IllegalArgumentException("邮箱已被注册！");
        }
        //密码加密
        if (user.getPassword()==null){
            throw new IllegalArgumentException("密码不能为空！");
        }
        user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
        user.setStatus(1);
        return this.save(user);
    }

    @Override
    public String login(String username, String password) {
        //登录验证，验证是否正确输入username，password
        if (StringUtils.isEmpty( username) && StringUtils.isEmpty(password)){
            throw new IllegalArgumentException("用户名或密码不能为空！");
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();//实现查询条件对象
        //根据用户名和密码查询状态为在用的用户
        queryWrapper.eq("username", username)
                .eq("password",DigestUtils.md5DigestAsHex(password.getBytes()))
                .eq("status",1);
        User user = this.getOne(queryWrapper);
        if (user== null){
            throw new IllegalArgumentException("用户名或密码错误，请查证后重新操作！");
        }
        //为找到的用户生成 token
        String token = tokenUtil.generateToken();
        //将token保存到redis中,同时设定有效时长
        redisUtil.set("user:token:"+token,user.getId().toString(),30, TimeUnit.MINUTES);
        //建立用户id与token的映射
        redisUtil.set("user:id:"+user.getId(),token,30, TimeUnit.MINUTES);
        return token;
    }

    @Override
    public User getUserByToken(String token) {
        //查询redis缓存中是否有token
        if(!tokenUtil.validateToken(token)){
            return null;
        }
        //从redis中获取token映射的用户id
        Object userIdObj=redisUtil.get("user:token:"+ token);
        if (userIdObj==null){
            return null;
        }
        try{
            Long userId=Long.valueOf(userIdObj.toString());//获取redis中的userid
            //根据userid查询用户
            User user=this.getById(userId);
            if (user!=null){
                //刷新token值
                redisUtil.set("user:token:"+token,user.getId().toString(),30, TimeUnit.MINUTES);
                redisUtil.set("user:id:"+user.getId(),token,30, TimeUnit.MINUTES);
            }
        }catch (Exception e){
            System.err.println("没有找到与这个token适配的User:"+e.getMessage());
        }
        return null;
    }

    @Override
    public boolean logout(String token) {
        User user=this.getUserByToken(token);
        if (user!=null){
            //刷新token值
            redisUtil.delete("user:token:"+token);
            redisUtil.delete("user:id:"+user.getId());
            return true;
        }
        return false;
    }

   public boolean validateToken(String token){
        return tokenUtil.hasKey("user:token:"+token);
   }
}
